#include "lcd_init.h"
#include "stdio.h"
#include <string.h>
// #include "app.h"

typedef void (*FunType)(void);
//**********************************write function begin********************************************
void wr_cmd_4spi_8bcs(uint8_t par)
{
    LCD_DCXLow();
    LCD_CSLow();

    LCD_SCLLow();
    if (par & 0x80)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x40)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x20)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x10)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x08)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x04)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x02)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x01)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_CSHigh();
    LCD_DCXHigh();
    //HAL_Delay(5);
}
void wr_dat_4spi_8bcs(uint8_t par)
{
    LCD_DCXHigh();
    LCD_CSLow();

    LCD_SCLLow();
    if (par & 0x80)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x40)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x20)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x10)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x08)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x04)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x02)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_SCLLow();
    if (par & 0x01)
        LCD_SDAHigh();
    else
        LCD_SDALow();
    LCD_SCLHigh();

    LCD_CSHigh();
    LCD_DCXHigh();
    //HAL_Delay(1);
}
void wr_cmd_parall1_8(uint16_t par)
{
    LCD_DCXLow();
    LCD_CSLow();
    LCD_WRLow();
    GPIOB->ODR = par;

    LCD_WRHigh();
}
void wr_dat_parall1_8(uint16_t par)
{
    LCD_DCXHigh();
    LCD_WRLow();
    GPIOB->ODR = par;

    LCD_WRHigh();
}
void wr_cmd_parall2_8(uint16_t par)
{
    LCD_DCXLow();
    LCD_CSLow();
    LCD_WRLow();
    GPIOB->ODR = par << 1;

    LCD_WRHigh();
}
void wr_dat_parall2_8(uint16_t par)
{
    LCD_DCXHigh();
    LCD_WRLow();
    GPIOB->ODR = par << 1;

    LCD_WRHigh();
}
//**********************************read function begin********************************************
void pb_out(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // db 0-7
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
                          GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
void pb_in(void)
{
    GPIO_InitTypeDef GPIO_InitStruct = {0};

    // db 0-7
    GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 |
                          GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
}
uint8_t i801_read_byte(void)
{
    uint8_t v;

    LCD_DCXHigh();
    LCD_RDLow();
    v = GPIOB->IDR;
    LCD_RDHigh();

    return v;
}
void rd_parall1_8(uint8_t c, uint8_t *d, uint32_t l)
{
    uint8_t buf[128];

    wr_cmd_parall1_8(c);
    pb_in();
    for (int i = 0; i < l; i++)
    {
        buf[i] = i801_read_byte();
    }
    LCD_CSHigh();
    pb_out();
    memcpy(d, buf, l);
}
//**********************************write display begin********************************************
void wr_displ_parall1_8(uint8_t color)
{
    LCD_DCXHigh();
    LCD_WRLow();
    GPIOB->ODR = color;
    LCD_WRHigh();
}
void wr_displ_parall2_18(uint16_t color1, uint16_t color2)
{
    LCD_DCXHigh();
    LCD_WRLow();
    if (color1 & 0x02)
        HAL_GPIO_WritePin(DB17_GPIO_Port, DB17_Pin, GPIO_PIN_SET);
    else
        HAL_GPIO_WritePin(DB17_GPIO_Port, DB17_Pin, GPIO_PIN_RESET);
    if (color1 & 0x01)
        HAL_GPIO_WritePin(DB16_GPIO_Port, DB16_Pin, GPIO_PIN_SET);
    else
        HAL_GPIO_WritePin(DB16_GPIO_Port, DB16_Pin, GPIO_PIN_RESET);
    GPIOB->ODR = color2;
    LCD_WRHigh();
}

void LCD_WR_REG(uint8_t par)
{
    wr_cmd_4spi_8bcs(par);
}

void LCD_WR_DATAX(uint8_t par)
{
    wr_dat_4spi_8bcs(par);
}

void delay(uint32_t ms)
{
    HAL_Delay(ms);
}

void C213NAA(void)
{
    LCD_RSTHigh();
    HAL_Delay(10);
    LCD_RSTLow();
    HAL_Delay(10);
    LCD_RSTHigh();
    HAL_Delay(200);
    LCD_WR_REG(0xD6); // NVM Load Control
    LCD_WR_DATAX(0X17);
    LCD_WR_DATAX(0X02);
    LCD_WR_REG(0xD1); // Booster Enable
    LCD_WR_DATAX(0X01);

    LCD_WR_REG(0xC0);   // Gate Voltage Setting
    LCD_WR_DATAX(0X0E); // VGH=15V
    LCD_WR_DATAX(0X0A); // VGL=-7.5V

    LCD_WR_REG(0xC1);   // VSHP Setting
    LCD_WR_DATAX(0X41); // VSHP1=5V
    LCD_WR_DATAX(0X41); // VSHP2=5V
    LCD_WR_DATAX(0X41); // VSHP3=5V
    LCD_WR_DATAX(0X41); // VSHP4=5V

    LCD_WR_REG(0xC2);   // VSLP Setting
    LCD_WR_DATAX(0X32); // VSLP1=1V
    LCD_WR_DATAX(0X32); // VSLP2=1V
    LCD_WR_DATAX(0X32); // VSLP3=1V
    LCD_WR_DATAX(0X32); // VSLP4=1V

    LCD_WR_REG(0xC4);   // VSHN Setting
    LCD_WR_DATAX(0X4B); // VSHN1=-4V
    LCD_WR_DATAX(0X4B); // VSHN2=-4V
    LCD_WR_DATAX(0X4B); // VSHN3=-4V
    LCD_WR_DATAX(0X4B); // VSHN4=-4V

    LCD_WR_REG(0xC5);   // VSLN Setting
    LCD_WR_DATAX(0X00); // VSLN1=1V
    LCD_WR_DATAX(0X00); // VSLN2=1V
    LCD_WR_DATAX(0X00); // VSLN3=1V
    LCD_WR_DATAX(0X00); // VSLN4=1V

    LCD_WR_REG(0xB2);   // Frame Rate Control
    LCD_WR_DATAX(0X12); // HPM=32hz ; LPM=1hz

    LCD_WR_REG(0xB3);   // Update Period Gate EQ Control in HPM
    LCD_WR_DATAX(0XE5); //
    LCD_WR_DATAX(0XF6); //
    LCD_WR_DATAX(0X05); // HPM EQ Control
    LCD_WR_DATAX(0X46); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X76); //
    LCD_WR_DATAX(0X45); //

    LCD_WR_REG(0xB4);   // Update Period Gate EQ Control in LPM
    LCD_WR_DATAX(0X05); // LPM EQ Control
    LCD_WR_DATAX(0X46); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X77); //
    LCD_WR_DATAX(0X76); //
    LCD_WR_DATAX(0X45); //

    LCD_WR_REG(0xB7);   // Source EQ Enable
    LCD_WR_DATAX(0X13); //
    LCD_WR_REG(0xB0);   // Gate Line Setting
    LCD_WR_DATAX(0X3F); // 252 line

    LCD_WR_REG(0x11); // Sleep out
    delay(120);

    LCD_WR_REG(0xD8); // HPM=32Hz
    LCD_WR_DATAX(0X80);
    LCD_WR_DATAX(0XE9);

    LCD_WR_REG(0xC9);   // Source Voltage Select
    LCD_WR_DATAX(0x00); // VSHP1; VSLP1 ; VSHN1 ; VSLN1

    LCD_WR_REG(0xC7); // ultra low power code
    LCD_WR_DATAX(0xC1);
    LCD_WR_DATAX(0x41);
    LCD_WR_DATAX(0x26);

    LCD_WR_REG(0x36);   // Memory Data Access Control
    LCD_WR_DATAX(0X48); // MX=0 ; DO=0

    LCD_WR_REG(0x3A);   // Data Format Select
    LCD_WR_DATAX(0X11); // 10:4write for 24bit ; 11: 3write for 24bit

    LCD_WR_REG(0xB9);   // Gamma Mode Setting
    LCD_WR_DATAX(0X20); // 20: Mono 00:4GS

    LCD_WR_REG(0xB8);   // Panel Setting
    LCD_WR_DATAX(0X25); // dot inversion; one line interval; dot inversion

    LCD_WR_REG(0x21); // Inverse

    // WRITE RAM 122x250
    LCD_WR_REG(0x2A); // Column Address Setting
    LCD_WR_DATAX(0X19);
    LCD_WR_DATAX(0X23);
    LCD_WR_REG(0x2B); // Row Address Setting
    LCD_WR_DATAX(0X00);
    LCD_WR_DATAX(0X7C);

    LCD_WR_REG(0x35);   // TE
    LCD_WR_DATAX(0X00); //

    LCD_WR_REG(0xD0);   // Auto power down
    LCD_WR_DATAX(0XFF); //

    // clealddram();

    LCD_WR_REG(0x39); // 0x39 low power  0x38 high power
    LCD_WR_REG(0x29); // DISPLAY ON
}

void S290NAA_Init(void)
{
    LCD_RSTHigh();
    HAL_Delay(120);
    LCD_RSTLow();
    HAL_Delay(120);
    LCD_RSTHigh();
    HAL_Delay(200);
    /****************并口1-8bit*****************/
    wr_cmd_parall1_8(0xD6); // NVM Load Control
    wr_dat_parall1_8(0X17);
    wr_dat_parall1_8(0X02);
    wr_cmd_parall1_8(0xD1); // Booster Enable
    wr_dat_parall1_8(0X01);

    wr_cmd_parall1_8(0xC0); // Gate Voltage Setting
    wr_dat_parall1_8(0X08); // VGH=12V
    wr_dat_parall1_8(0X02); // VGL=-6V

    wr_cmd_parall1_8(0xC1); // VSHP Setting
    wr_dat_parall1_8(0X23); // VSHP1=4.4V
    wr_dat_parall1_8(0X23); // VSHP2=4.4V
    wr_dat_parall1_8(0X23); // VSHP3=4.4V
    wr_dat_parall1_8(0X23); // VSHP4=4.4V

    wr_cmd_parall1_8(0xC2); // VSLP Setting
    wr_dat_parall1_8(0X1E); // VSLP1=0.6V
    wr_dat_parall1_8(0X1E); // VSLP2=0.6V
    wr_dat_parall1_8(0X1E); // VSLP3=0.6V
    wr_dat_parall1_8(0X1E); // VSLP4=0.6V

    wr_cmd_parall1_8(0xC4); // VSHN Setting
    wr_dat_parall1_8(0X3C); // VSHN1=-3.7V
    wr_dat_parall1_8(0X3C); // VSHN2=-3.7V
    wr_dat_parall1_8(0X3C); // VSHN3=-3.7V
    wr_dat_parall1_8(0X3C); // VSHN4=-3.7V

    wr_cmd_parall1_8(0xC5); // VSLN Setting
    wr_dat_parall1_8(0X14); // VSLN1=0.6V
    wr_dat_parall1_8(0X14); // VSLN2=0.6V
    wr_dat_parall1_8(0X14); // VSLN3=0.6V
    wr_dat_parall1_8(0X14); // VSLN4=0.6V

    wr_cmd_parall1_8(0xD8); // OSC Setting
    wr_dat_parall1_8(0xA6);
    wr_dat_parall1_8(0xE9);

    wr_cmd_parall1_8(0xB2); // Frame Rate Control
    wr_dat_parall1_8(0X02); // HPM=16hz ; LPM=1hz

    wr_cmd_parall1_8(0xB3); // Update Period Gate EQ Control in HPM
    wr_dat_parall1_8(0XE5); // HPM EQ Control
    wr_dat_parall1_8(0XF6);
    wr_dat_parall1_8(0X05);
    wr_dat_parall1_8(0X46);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X76);
    wr_dat_parall1_8(0X45);

    wr_cmd_parall1_8(0xB4); // Update Period Gate EQ Control in LPM
    wr_dat_parall1_8(0X05); // LPM EQ Control
    wr_dat_parall1_8(0X46);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X77);
    wr_dat_parall1_8(0X76);
    wr_dat_parall1_8(0X45);

    wr_cmd_parall1_8(0x62); // Gate Timing Control
    wr_dat_parall1_8(0X32);
    wr_dat_parall1_8(0X03);
    wr_dat_parall1_8(0X1F);

    wr_cmd_parall1_8(0xC7); // Ultra Low Power Mode
    wr_dat_parall1_8(0XC1);
    wr_cmd_parall1_8(0x41);
    wr_dat_parall1_8(0X26);

    wr_cmd_parall1_8(0xB7); // Source EQ enable
    wr_dat_parall1_8(0X13);

    wr_cmd_parall1_8(0xB0); // Gate Line Setting
    wr_dat_parall1_8(0X78); // 480 line

    wr_cmd_parall1_8(0x11); // Sleep out
    HAL_Delay(200);

    wr_cmd_parall1_8(0xC9); // Source Voltage Select
    wr_dat_parall1_8(0x00); // VSHP1; VSLP1 ; VSHN1 ; VSLN1

    wr_cmd_parall1_8(0x36); // Memory Data Access Control
    wr_dat_parall1_8(0X48); // MX=0 ; DO=0

    wr_cmd_parall1_8(0x3A); // Data Format Select
    wr_dat_parall1_8(0X30); // M8C=1, 8color ; RGB64=1, BGR order ; BPS=0, 4write for 24 bit

    wr_cmd_parall1_8(0x21); //

    wr_cmd_parall1_8(0xB9); // Gamma Mode Setting
    wr_dat_parall1_8(0X20); // 20: Mono 00:4GS

    wr_cmd_parall1_8(0xB8); // Panel Setting
    wr_dat_parall1_8(0X29); // one line interlace; frame interval; dot inversion

    // WRITE RAM 210X480
    wr_cmd_parall1_8(0x2A); // Column Address Setting
    wr_dat_parall1_8(0X04);
    wr_dat_parall1_8(0X38);

    wr_cmd_parall1_8(0x2B); // Row Address Setting
    wr_dat_parall1_8(0X00);
    wr_dat_parall1_8(0XEF);

    wr_cmd_parall1_8(0x35); // TE enable
    wr_dat_parall1_8(0X00);

    wr_cmd_parall1_8(0xD0); // Auto power down
    wr_dat_parall1_8(0XFF);

    wr_cmd_parall1_8(0x39); // 0x39=LPM; 0x38=HPM
    wr_cmd_parall1_8(0x29); // DISPLAY ON
}
// void Filllcd_Area(uint16_t _usX, uint16_t _usY, uint16_t _usWidth , uint16_t _usHeight, uint16_t color)
// void Filllcd_Area(uint32_t color)
void Filllcd_Area(uint16_t color)
{
    uint32_t x = 0;
    uint32_t y = 0;
    /*//显示区域限制
    wr_cmd_4spi_8bcs(GC9A01_CMD_CASETF);
    wr_dat_4spi_8bcs(_usX >> 8);
    wr_dat_4spi_8bcs(_usX );
    wr_dat_4spi_8bcs( (_usX + _usWidth - 1) >> 8);
    wr_dat_4spi_8bcs( (_usX + _usWidth - 1) );

    wr_cmd_4spi_8bcs(GC9A01_CMD_RASETF );
    wr_dat_4spi_8bcs(_usY >> 8);
    wr_dat_4spi_8bcs(_usY );
    wr_dat_4spi_8bcs( (_usY + _usHeight - 1) >> 8 );
    wr_dat_4spi_8bcs( (_usY + _usHeight - 1) );
    //准备接收数据*/
    /*wr_cmd_4spi_8bcs(0x2c);

    //uint8_t colorred = color >> 16;
    uint8_t color1 = (color & 0xff00) >> 8;
    uint8_t color2 = (color & 0xff);
    //uint8_t color1,color2;
    for( y=0; y < LCD_Height; y++ )
        {for( x=0; x < LCD_Width; x++ )
        {
            wr_dat_4spi_8bcs( 0xf8);
            wr_dat_4spi_8bcs( 0x00 );
        }
    }*/
    /*wr_c2c();

    for( y=0; y < LCD_Height ; y++ )
        {for( x=0; x < LCD_Width; x++ )
        {
            wr_num(0xf8);
            wr_num(0x00);
        }
    }*/
    /*wr_cmd_parall1_8(0x2a);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(167);

    wr_cmd_parall1_8(0x2b);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x00);
    wr_dat_parall1_8(0x01);
    wr_dat_parall1_8(0x3F);*/
    wr_cmd_parall1_8(0x2A); // Column Address Setting
    wr_dat_parall1_8(0X17);
    wr_dat_parall1_8(0X24);
    wr_cmd_parall1_8(0x2B); // Row Address Setting
    wr_dat_parall1_8(0X00);
    wr_dat_parall1_8(0XBF);

    wr_cmd_parall1_8(0X2C);
    // uint8_t colorred = color >> 16;
    // uint8_t color1 = (color & 0xff00) >> 8;
    // uint8_t color2 = (color & 0xff);
    for (y = 0; y < 384; y++)
    {
        for (x = 0; x < 21; x++)
        {
            wr_displ_parall1_8(color);
            // wr_displ_parall1_8(0x00);
            // wr_displ_parall1_8(0x00);

            /*wr_displ_parall1_8(colorred);
            wr_displ_parall1_8(color1);
            wr_displ_parall1_8(color2);	*/
            // wr_displ_parall2_18_H(0x0003);
            // wr_displ_parall2_18_L(0xF000);
        }
    }
}
